package com.imooc.ecommerce.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imooc.ecommerce.account.AddressInfo;
import com.imooc.ecommerce.common.TableId;
import com.imooc.ecommerce.entity.EcommerceAddress;
import com.imooc.ecommerce.filter.AccessContext;
import com.imooc.ecommerce.mapper.EcommerceAddressMapper;
import com.imooc.ecommerce.service.IAddressService;
import com.imooc.ecommerce.vo.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户地址相关服务接口实现
 * @Author: zhangshao
 * @Since: 2023/11/28 10:52
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AddressServiceImpl extends ServiceImpl<EcommerceAddressMapper, EcommerceAddress>
		implements IAddressService {


	/**
	 * 存储多个地址信息
	 * @param addressInfo 用户地址信息
	 * @return
	 */
	@Override
	public TableId createAddressInfo(AddressInfo addressInfo) {

		//不能从参数中获取用户的id信息
		LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();

		List<EcommerceAddress> ecommerceAddressList = addressInfo.getAddressItems().stream()
				.map(e -> EcommerceAddress.to(loginUserInfo.getId(), e)).collect(Collectors.toList());
		//保存到数据库并把返回记录的id给调用方
		this.saveBatch(ecommerceAddressList);
		List<Long> ids = ecommerceAddressList.stream().map(EcommerceAddress::getId).collect(Collectors.toList());

		log.info("create address info :[{}],[{}]", loginUserInfo.getId(), JSON.toJSONString(ids));

		return new TableId(ids.stream().map(TableId.Id::new).collect(Collectors.toList()));
	}

	@Override
	public AddressInfo getCurrentAddressInfo() {
		LoginUserInfo loginUserInfo = AccessContext.getLoginUserInfo();
		// 根据userId查询到用户的地址信息，在实现转换
		List<EcommerceAddress> ecommerceAddresses = new LambdaQueryChainWrapper<>(this.baseMapper)
				.eq(EcommerceAddress::getUserId, loginUserInfo.getId()).list();
		List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream().map(EcommerceAddress::toAddressItem)
				.collect(Collectors.toList());

		return new AddressInfo(loginUserInfo.getId(), addressItems);
	}

	@Override
	public AddressInfo getAddressInfoById(Long id) {
		EcommerceAddress ecommerceAddress = this.baseMapper.selectById(id);
		if (null == ecommerceAddress) {
			throw new RuntimeException("address is not exist");
		}
		return new AddressInfo(ecommerceAddress.getUserId(),
				Collections.singletonList(ecommerceAddress.toAddressItem()));
	}

	@Override
	public AddressInfo getAddressInfoByTableId(TableId tableId) {
		List<Long> ids = tableId.getIds().stream().map(TableId.Id::getId).collect(Collectors.toList());
		log.info("get address info by table id :[{}]", JSON.toJSONString(ids));
		List<EcommerceAddress> ecommerceAddresses = this.getBaseMapper().selectBatchIds(ids);
		if (CollectionUtil.isEmpty(ecommerceAddresses)) {
			return new AddressInfo(-1L, Collections.emptyList());
		}
		List<AddressInfo.AddressItem> addressItems = ecommerceAddresses.stream().map(EcommerceAddress::toAddressItem).collect(
				Collectors.toList());


		return new AddressInfo(ecommerceAddresses.get(0).getUserId(),addressItems);
	}
}
